// 1. class的基本用法 继承和类型约束


interface Vnode {
    tag: string
    text?: string
    props?: {
        id?: number | string
        key?: number | string | object
    }
    children?: Vnode[]
}
class Dom {
    constructor () {

    }
    createElement(el: string): HTMLElement {
        return document.createElement(el)
    }

    setText(el: Element, text: string | null): void {
        el.textContent = text
    }
    render (createElement: Vnode): HTMLElement {
        const el = this.createElement(createElement.tag)
        if (createElement.children && Array.isArray(createElement.children)) {
            createElement.children.forEach(item => {
                const child = this.render(item)
                el.appendChild(child)
            })
        } else if (createElement.text) {
            this.setText(el, createElement.text)
        }
        return el
    }
}

interface Options {
    el: string | HTMLElement
}
interface VueCls {
    init(): void
    options: Options
}
class Vue extends Dom implements VueCls {
    options: Options
    constructor (options: Options) {
        super()
        this.options = options
        this.init()
    }
    init () {
        let app = typeof this.options.el === 'string' ? document.querySelector(this.options.el) : this.options.el
        let data: Vnode = {
            tag: "div",
            props: {
                id: 1,
                key: 1
            },
            children: [
                {
                    tag: "div",
                    text: "子集1",
                },
                {
                    tag: "div",
                    text: "子集2"
                },
                {
                    tag: "div",
                    text: "子集3"
                }
            ]
        }
        app?.appendChild(this.render(data))
        console.log(app)
        this.mount(app as Element)
    }
    mount (app: Element) {
        document.body.append(app)
    }
}
const v = new Vue({
    el: '#app'
})